
var express = require("express");
var path = require("path");
var fsp = require("fs/promises");

// // 用于接收post数据  并对数据做处理(第三方 运行依赖)  => express已经内置
// var bodyParser = require("body-parser");  // 老版本

var app = express(); //创建服务器  

// 配置站点 (放前端相关的文件)
app.use(express.static(path.join(__dirname, "../site")));


app.use(express.json());//用于解析application/json
/* 前端发送格式   req.send(JSON.stringify({name:1}))    接收json类型的字符串(此时不需要设置请求头)  */


app.use(express.urlencoded({ extended: true }));   //用于解析application/x-www-urlencoded
/* 前端发送格式   req.send("name=www&age=18")    接收参数数据字符串 (需要设置请求头)  */
// { extended: false }   是否深度解析数据

// 等价于
// app.use(bodyParser.json()); // for parsing application/json   //用于解析application/json
/* 前端发送格式   req.send(JSON.stringify({name:1}))    接收json类型的字符串(此时不需要设置请求头)  */

// app.use(bodyParser.urlencoded({ extended: true })); //用于解析application/x-www-urlencoded
/* 前端发送格式   req.send("name=www&age=18")    接收参数数据字符串 (需要设置请求头)  */
// { extended: false }   是否深度解析数据


var db = path.join(__dirname, "./data");

// 自定义路由  => 此处配置后端接口(返回json格式字符串)  => 数据增删改查
// {code,message,data,list}
// code  返回浏览器查询的结果码(增删改查)   100(参数有问题)  200(增删改查成功)   300(失败)  404(文件不存在)   500(服务器蹦掉了)
// message  返回浏览器查询的结果描述
// data     单条数据(对象)
// list     多条数据(数组)


// app.get() 可以理解为监听操作, 浏览器以get方式向/grade发送的请求
app.get("/grade", function (req, res) {
    fsp.readFile(path.join(db, "./grade.json"), "utf-8").then((list) => { // 读取文件时返回的就是文本(json字符串)
        // res.end(list); // http模块内置的

        // express中封装的
        res.send(list);
    }).catch(err => {
        res.end(JSON.stringify(err))
    })
})

app.get("/grade/searchGradeById", function (req, res) {
    // req.query  接收前端以get方式传递的数据
    // req.body   接收前端以post方式传递的数据
    if (Object.keys(req.query).includes("id")) {  // 是否存在属性名为"id"
        fsp.readFile(path.join(db, "./grade.json"), "utf-8").then((list) => { // 读取文件时返回的就是文本(json字符串)
            list = JSON.parse(list); //将json字符串解析为json对象(对象/数组)

            var result = list.find(v => v.id == req.query.id);

            // if (result) {
            //     res.end(JSON.stringify(result))
            // } else {
            //     res.end("数据不存在")
            // }
            if (result) {
                var obj = {
                    code: 200,  // 自定义属性表示查询的结果  (200  404  500)
                    message: "OK",
                    data: result,
                }
                res.end(JSON.stringify(obj))
            } else {

                var obj = {
                    code: 404,  // 自定义属性表示查询的结果  (200  404  500)
                    message: "Not Found",
                }
                res.send(JSON.stringify(obj))
            }

        }).catch(err => {
            res.send(JSON.stringify(err));
        })
    } else {
        var obj = {
            code: 100,
            message: "请传入完整参数",
        }
        // res.end(JSON.stringify(obj))
        res.send(obj);  // 
        // res.json(obj);
    }
})


app.get("/user", function (req, res) {
    fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((list) => { // 读取文件时返回的就是文本(json字符串)
        // res.end(list); // http模块内置的

        list = list || "[]";

        // express中封装的
        res.send(list);
    }).catch(err => {
        res.send(JSON.stringify(err))
    })
})


// 用户新增: 
// 接收用户传入的数据, 存储到数据库(userinfo)  
// 分析:  需要存储 user pwd phone email  nickIcon(头像 默认"")

// 流程:
// 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
// 都不存在 => 可以注册

// console.log(Object.hasOwn({ a: 1, b: 2 }, "a"));

// app.get("/user/add", function (req, res) {
//     // let data = { user: "a123123", pwd: 123123, phone: "17386141516", email: "a123123@qq.com" }; //模拟前端传入的数据
//     let data = req.query; // 浏览器以get方式传递的数据
//     console.log("接收的数据", data);

//     // Object.hasOwn(obj,key)   判断对象中是否存在某个键名
//     /* if (!Object.hasOwn(data, "user")) {
//         res.send({
//             code: 100,
//             message: "请传入用户名",
//         })
//     } else if (!Object.hasOwn(data, "pwd")) {
//         res.send({
//             code: 100,
//             message: "请传入密码",
//         })
//     }*/

//     // 判断是否存在指定的键名(字段名)  => 接收数据的字段名后端规定
//     if (Object.hasOwn(data, "user") && Object.hasOwn(data, "pwd") && Object.hasOwn(data, "phone") && Object.hasOwn(data, "email")) {
//         // 无脑覆盖  => 最终只有一个
//         // fsp.writeFile(path.join(db, "./userinfo.json"), JSON.stringify(data), { encoding: "utf-8", flag: "a" }).then(() => {
//         //     res.send({
//         //         code: 200,
//         //         message: "注册成功",
//         //     })
//         // }).catch(err => {
//         //     res.send({
//         //         code: 300,
//         //         message: "注册失败",
//         //         error: err.message // err 错误对象 err.message 报错的信息
//         //     })
//         // })

//         // 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
//         fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((result) => {

//             result = result || "[]";  // 如果userinfo中不存在任何内容(读取后"") 默认空数组 ("字符串")
//             list = JSON.parse(result); // 将json字符串转化为 js对象(数组)

//             if (list.length > 0) { // 有数据
//                 if (list.find(v => v.user == data.user)) {
//                     res.send({
//                         code: 300,
//                         message: "用户名已被注册",
//                     })
//                 } else if (list.find(v => v.phone == data.phone)) {
//                     res.send({
//                         code: 300,
//                         message: "手机号已被注册",
//                     })
//                 } else if (list.find(v => v.email == data.email)) {
//                     res.send({
//                         code: 300,
//                         message: "邮箱已被注册",
//                     })
//                 } else {
//                     list.push(data);
//                     fsp.writeFile(path.join(db, "./userinfo.json"), JSON.stringify(list), { encoding: "utf-8", flag: "w" }).then(() => {
//                         res.send({
//                             code: 200,
//                             message: "注册成功",
//                         })
//                     }).catch(err => {
//                         res.send({
//                             code: 300,
//                             message: "注册失败",
//                             error: err.message // err 错误对象 err.message 报错的信息
//                         })
//                     })

//                 }

//             } else { // 没有数据 => 数据库中一条数据都没有
//                 list.push(data);

//                 fsp.writeFile(path.join(db, "./userinfo.json"), JSON.stringify(list), { encoding: "utf-8", flag: "w" }).then(() => {
//                     res.send({
//                         code: 200,
//                         message: "注册成功",
//                     })
//                 }).catch(err => {
//                     res.send({
//                         code: 300,
//                         message: "注册失败",
//                         error: err.message // err 错误对象 err.message 报错的信息
//                     })
//                 })

//             }



//         }).catch(err => {
//             res.send({
//                 code: 500,
//                 message: "读取失败",  // 服务器内部读取文件失败
//                 error: err.message // err 错误对象 err.message 报错的信息
//             })
//         })
//     } else {
//         res.send({
//             code: 100,
//             message: "请传入完整参数",
//         })
//     }

// })

app.get("/user/isExistUser", function (req, res) {
    let { user } = req.query;

    // Object.hasOwn(req.query, "user")  判断对象中是否存在键名(字段名),不考虑健值
    // var user = req.query.user  // 取req.query的user属性的属性值
    if (Object.hasOwn(req.query, "user")) {

        // 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
        fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((result) => {

            result = result || "[]";  // 如果userinfo中不存在任何内容(读取后"") 默认空数组 ("字符串")
            list = JSON.parse(result); // 将json字符串转化为 js对象(数组)

            if (!list.find(v => v.user == user)) {
                res.send({
                    code: 200,
                    message: "可以使用的用户名",
                })
            } else {
                res.send({
                    code: 300,
                    message: "用户名已被注册",
                })
            }

        }).catch(err => {
            res.send({
                code: 500,
                message: "读取失败",  // 服务器内部读取文件失败
                error: err.message // err 错误对象 err.message 报错的信息
            })
        })
    } else {
        res.send({
            code: 100,
            message: "请传入完整参数",
        })
    }
})

app.get("/user/isExistPhone", function (req, res) {
    if (Object.hasOwn(req.query, "phone")) {
        let { phone } = req.query;

        // 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
        fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((result) => {

            result = result || "[]";  // 如果userinfo中不存在任何内容(读取后"") 默认空数组 ("字符串")
            list = JSON.parse(result); // 将json字符串转化为 js对象(数组)

            if (!list.find(v => v.phone == phone)) {
                res.send({
                    code: 200,
                    message: "可以使用的手机号",
                })
            } else {
                res.send({
                    code: 300,
                    message: "手机号已被注册",
                })
            }

        }).catch(err => {
            res.send({
                code: 500,
                message: "读取失败",  // 服务器内部读取文件失败
                error: err.message // err 错误对象 err.message 报错的信息
            })
        })
    } else {
        res.send({
            code: 100,
            message: "请传入完整参数",
        })
    }
})

app.get("/user/isExistEmail", function (req, res) {
    if (Object.hasOwn(req.query, "email")) {
        let { email } = req.query;

        // 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
        fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((result) => {

            result = result || "[]";  // 如果userinfo中不存在任何内容(读取后"") 默认空数组 ("字符串")
            list = JSON.parse(result); // 将json字符串转化为 js对象(数组)

            if (!list.find(v => v.email == email)) {
                res.send({
                    code: 200,
                    message: "可以使用的邮箱",
                })
            } else {
                res.send({
                    code: 300,
                    message: "邮箱已被注册",
                })
            }

        }).catch(err => {
            res.send({
                code: 500,
                message: "读取失败",  // 服务器内部读取文件失败
                error: err.message // err 错误对象 err.message 报错的信息
            })
        })
    } else {
        res.send({
            code: 100,
            message: "请传入完整参数",
        })
    }
})



// post类型接口 接收数据的方式和get不一样(需要额外处理)  => post接口不好直接测试
// (1) 先写成get 在改为post (今天建议)
// (2) 自己新建页面 发送ajax请求  (low) 
// (3) 接口测试工具 postman

app.post("/user/add", function (req, res) {
    // let data = { user: "a123123", pwd: 123123, phone: "17386141516", email: "a123123@qq.com" }; //模拟前端传入的数据
    let data = req.body; // 浏览器以post方式传递的数据
    console.log("接收的数据", data);

    // 判断是否存在指定的键名(字段名)  => 接收数据的字段名后端规定
    if (Object.hasOwn(data, "user") && Object.hasOwn(data, "pwd") && Object.hasOwn(data, "phone") && Object.hasOwn(data, "email")) {

        // 注册之前需要判断用户名 手机号 邮箱是否存在  => 存在就不能注册
        fsp.readFile(path.join(db, "./userinfo.json"), "utf-8").then((result) => {

            result = result || "[]";  // 如果userinfo中不存在任何内容(读取后"") 默认空数组 ("字符串")
            list = JSON.parse(result); // 将json字符串转化为 js对象(数组)

            if (list.length > 0) { // 有数据
                if (list.find(v => v.user == data.user)) {
                    res.send({
                        code: 300,
                        message: "用户名已被注册",
                    })
                } else if (list.find(v => v.phone == data.phone)) {
                    res.send({
                        code: 300,
                        message: "手机号已被注册",
                    })
                } else if (list.find(v => v.email == data.email)) {
                    res.send({
                        code: 300,
                        message: "邮箱已被注册",
                    })
                } else {
                    list.push(data);
                    fsp.writeFile(path.join(db, "./userinfo.json"), JSON.stringify(list), { encoding: "utf-8", flag: "w" }).then(() => {
                        res.send({
                            code: 200,
                            message: "注册成功",
                        })
                    }).catch(err => {
                        res.send({
                            code: 300,
                            message: "注册失败",
                            error: err.message // err 错误对象 err.message 报错的信息
                        })
                    })

                }

            } else { // 没有数据 => 数据库中一条数据都没有
                list.push(data);

                fsp.writeFile(path.join(db, "./userinfo.json"), JSON.stringify(list), { encoding: "utf-8", flag: "w" }).then(() => {
                    res.send({
                        code: 200,
                        message: "注册成功",
                    })
                }).catch(err => {
                    res.send({
                        code: 300,
                        message: "注册失败",
                        error: err.message // err 错误对象 err.message 报错的信息
                    })
                })

            }



        }).catch(err => {
            res.send({
                code: 500,
                message: "读取失败",  // 服务器内部读取文件失败
                error: err.message // err 错误对象 err.message 报错的信息
            })
        })
    } else {
        res.send({
            code: 100,
            message: "请传入完整参数",
        })
    }

})

// post  /user/login     
// 参数:  user  pwd  

// (1) 参数校验
// (2) 对应用户查找用户是否存在   不存在:用户未注册
// (3) 存在  判断密码是否正确   正确: 登录成功  密码有误:用户名或密码有误

app.post("/user/login", async function (req, res) {
    // let data = { user: "a12313", pwd: "123123" }
    // let data = req.body;

    if (Object.hasOwn(req.body, "user") && Object.hasOwn(req.body, "pwd")) {
        let { user, pwd } = req.body;  // 用户传入的

        // (1) 判断用户是否注册
        try {
            var list = await fsp.readFile(path.join(db, "./userinfo.json"), "utf-8");  // 读取的字符串
            list = JSON.parse(list); //转数组

            var info = list.find(v => v.user == user);

            if (info) {
                if (info.pwd == pwd) {
                    res.send({
                        code: 200,
                        message: "登录成功",
                    })
                } else {
                    res.send({
                        code: 300,
                        message: "用户名或密码有误",
                    })
                }

            } else {
                res.send({
                    code: 300,
                    message: "用户未注册",
                })
            }




        } catch (err) { // 文件读取失败
            res.send({
                code: 300,
                message: err.message,
            })
        }





    } else {
        res.send({
            code: 100,
            message: "请传入完整参数",
        })
    }


})



// post  /grade/add
// get   /grade/searchGradeById
// get   /grade/del
// post   /grade/update







// 监听端口
app.listen(3000, () => {
    console.log("服务启动=>  http://localhost:3000");
})




